#include "mapeditor.h"

void mW_mapeditor_draw ()
{
	
	acquire_bitmap(mW_buffer_page);
	clear_to_color(mW_buffer_page, makecol(0x0, 0x0, 0x0));
	release_bitmap(mW_buffer_page);
	
	// draw the map
	if (mW_map_blit(mW_mapeditor_map, mW_buffer_page, mW_MAP_WIDTH, mW_MAP_HEIGHT, 0, 0) == 0)
	{
		printf("Error drawing map\n");
		return;
	}
	
	
	// draw the mapeditor tiles
	if (mW_mapeditor_draw_tiles(mW_buffer_page) == 0)
	{
		printf("Error drawing tiles\n");
		return;
	}
	
	
	// draw pieces of the mapeditor interface
	if (mW_mapeditor_draw_interface(mW_buffer_page) == 0)
	{
		printf("Error drawing the mapeditor interface\n");
		return;
	}
	
	
	// draw the interface
	if (mW_interface_draw(mW_buffer_page) == 0)
	{
		printf("Error drawing the interface\n");
		return;
	}
	
	
	if (mW_centered_text != NULL)
	{
		acquire_bitmap(mW_buffer_page);
		textout_centre_ex(mW_buffer_page, font, mW_centered_text, SCREEN_W/2, SCREEN_H/2, makecol(0xFF, 0xFF, 0xFF), makecol(0x0, 0x0, 0x0));
		release_bitmap(mW_buffer_page);
	}
	
	
	// blit mouse pointer
	mW_mouse_draw_pointer(mW_buffer_page);
	
	acquire_screen();
	blit(mW_buffer_page, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H);
	release_screen();
	
}



int mW_mapeditor_draw_interface (BITMAP * surface)
{
	
	int x, y = 0;
	
	// if mouse is over one of the selectable tiles
	if ((mW_mouse_x >= mW_mapeditor_tiles_left_pixel) && mW_mouse_x <= mW_mapeditor_tiles_left_pixel + (mW_TILE_SIZE * mW_mapeditor_tiles_per_row))
	{
		if ((mW_mouse_y >= mW_mapeditor_tiles_top_pixel) && mW_mouse_y <= mW_mapeditor_tiles_top_pixel + (mW_TILE_SIZE * mW_mapeditor_tiles_rows))
		{
			
			// find out what tile we're on in the x axis
			x = (mW_mouse_x - mW_mapeditor_tiles_left_pixel) / mW_TILE_SIZE;
			// now properly place the x pixel
			x = mW_mapeditor_tiles_left_pixel + (x * mW_TILE_SIZE);
			
			// find out what tile we're on in the y axis
			y = ((mW_mouse_y - mW_mapeditor_tiles_top_pixel) / mW_TILE_SIZE);
			// properly place y pixel
			y = mW_mapeditor_tiles_top_pixel + (y * mW_TILE_SIZE);
			
			// draw our tile_over image
			acquire_bitmap(mW_mapeditor_img_over_tile);
			masked_blit(mW_mapeditor_img_over_tile, surface, 0, 0, x, y, mW_TILE_SIZE, mW_TILE_SIZE);
			release_bitmap(mW_mapeditor_img_over_tile);
			
		}
		
	}
	// if the mouse is over a map tile
	if ((mW_mouse_x >= 0) && (mW_mouse_x <= (mW_MAP_WIDTH * mW_TILE_SIZE)))
	{
		if ((mW_mouse_y >= 0) && (mW_mouse_y <= (mW_MAP_HEIGHT * mW_TILE_SIZE)))
		{
			// get the x, y for where the tile the mouse is over
			x = mouse_x / mW_TILE_SIZE;
			y = mouse_y / mW_TILE_SIZE;
			
			// is this a valid x, y for this map?
			if ((x + mW_mapeditor_map->offset_x < mW_mapeditor_map->width) && (y + mW_mapeditor_map->offset_y < mW_mapeditor_map->height))
			{
				// draw the over_tile img
				masked_blit(mW_mapeditor_img_over_tile, surface, 0, 0, x * mW_TILE_SIZE, y * mW_TILE_SIZE, mW_TILE_SIZE, mW_TILE_SIZE);
			}
		}
	}
	
	return 1;
	
}



int mW_mapeditor_draw_tiles (BITMAP * surface)
{
	
	int i;
	int x, y;
	
	acquire_bitmap(surface);
	
	for (i = mW_mapeditor_top_tile; i < mW_mapeditor_tiles_per_row * mW_mapeditor_tiles_rows; i++)
	{
		
		
		x = i % mW_mapeditor_tiles_per_row;
		y = i / mW_mapeditor_tiles_per_row;
		
		if (i >= mW_NUM_TILES)
		{	
			rectfill(surface,
			         mW_mapeditor_tiles_left_pixel + (x * mW_TILE_SIZE),
			         mW_mapeditor_tiles_top_pixel + (y * mW_TILE_SIZE),
			         mW_mapeditor_tiles_left_pixel + ((x + 1) * mW_TILE_SIZE),
			         mW_mapeditor_tiles_top_pixel + ((y + 1) * mW_TILE_SIZE),
			         makecol(0x0, 0x0, 0x0));
		}
		else
		{
			blit(mW_tiles[i],
				 surface,
				 0,
				 0,
				 mW_mapeditor_tiles_left_pixel + (x * mW_TILE_SIZE),
				 mW_mapeditor_tiles_top_pixel + (y * mW_TILE_SIZE),
				 mW_TILE_SIZE,
				 mW_TILE_SIZE);
				 
			if (i == mW_mapeditor_selected_tile_id)
				masked_blit(mW_mapeditor_selected_tile,
					        surface,
					        0,
					        0,
					        mW_mapeditor_tiles_left_pixel + (x * mW_TILE_SIZE),
					        mW_mapeditor_tiles_top_pixel + (y * mW_TILE_SIZE),
					        mW_TILE_SIZE,
					        mW_TILE_SIZE);
			
		}
		
	}
	
	release_bitmap(surface);
	
	return 1;
	
}



int mW_mapeditor_handle_mouse ()
{
	
	int map_x, map_y;
	unsigned short tile_id;
	
	
	// setting a tile on the map
	if ((mouse_b & 1) && (mW_mapeditor_editing == mW_MAPEDITOR_EDITING_TILES))
	{
		
		/*
		 * THIS NEEDS DRASTIC CHANGING
		 */
		// if user clicked on the map portion of the mapeditor
		if ((mW_mouse_x >= 0) && (mW_mouse_x <= (mW_MAP_WIDTH * mW_TILE_SIZE)))
		{
			if ((mW_mouse_y >= 0) && (mW_mouse_y <= (mW_MAP_HEIGHT * mW_TILE_SIZE)))
			{
				// find out what x, y on the map this pixel corresponds to
				map_x = mW_map_get_x_tile(mW_mapeditor_map, mW_mouse_x);
				map_y = mW_map_get_y_tile(mW_mapeditor_map, mW_mouse_y);
				
				// is this a valid x, y?
				if ((map_x >= 0) && (map_y >= 0))
				{
					// set map location tile_id to selected tile_id
					mW_mapeditor_map->locations[(unsigned short) map_x][(unsigned short) map_y]->tile_id = mW_mapeditor_selected_tile_id;
				}
			}
		}
		// selecting current selected_tile_id
		else if ((mW_mouse_x >= mW_mapeditor_tiles_left_pixel) && (mW_mouse_x <= mW_mapeditor_tiles_left_pixel * mW_mapeditor_tiles_per_row * mW_TILE_SIZE))
		{
			if ((mW_mouse_x >= mW_mapeditor_tiles_top_pixel) && (mW_mouse_x <= mW_mapeditor_tiles_top_pixel * mW_mapeditor_tiles_rows * mW_TILE_SIZE))
			{
				// find out what tile this corresponds to
				tile_id = (mW_mouse_x - mW_mapeditor_tiles_left_pixel) / mW_TILE_SIZE;
				tile_id += ((mW_mouse_y - mW_mapeditor_tiles_top_pixel) / mW_TILE_SIZE) * mW_mapeditor_tiles_per_row;
				
				// is this a valid tile_id
				if (tile_id <= mW_NUM_TILES)
					mW_mapeditor_selected_tile_id = tile_id;
			}
		}
		
	}
	// setting terrain passable
	else if ((mouse_b & 1) && (mW_mapeditor_editing == mW_MAPEDITOR_EDITING_PASSABLE))
	{
		
		// get tile where user clicked
		map_x = mW_map_get_x_tile(mW_mapeditor_map, mW_mouse_x);
		map_y = mW_map_get_y_tile(mW_mapeditor_map, mW_mouse_y);
		
		// is it a valid place?
		if ((map_x >= 0) && (map_y >= 0))
		{

			mW_mapeditor_map->locations[(unsigned short) map_x][(unsigned short) map_y]->flags |= mW_MAP_LOCATION_BIT_PASSABLE;

		}
		
	}
	// setting terrain nonpassable
	else if ((mouse_b & 1) && (mW_mapeditor_editing == mW_MAPEDITOR_EDITING_NONPASSABLE))
	{
		
		// get tile where user clicked
		map_x = mW_map_get_x_tile(mW_mapeditor_map, mW_mouse_x);
		map_y = mW_map_get_y_tile(mW_mapeditor_map, mW_mouse_y);
		
		// is it a valid place?
		if ((map_x >= 0) && (map_y >= 0))
		{

			mW_mapeditor_map->locations[(unsigned short) map_x][(unsigned short) map_y]->flags &= ~mW_MAP_LOCATION_BIT_PASSABLE;

		}
		
	}
	
	
	return 1;
	
}
				


int mW_mapeditor_loop ()
{

	char key;
	int keep_map_editing = 1;
	int interface_input;
	
	mW_mapeditor_selected_tile_id = 0;
	
	mW_mapeditor_top_tile = 0;
	mW_mapeditor_img_over_tile = load_bitmap("data/interface_imgs/mapeditor_over_tile.bmp", NULL);
	mW_mapeditor_selected_tile = load_bitmap("data/interface_imgs/mapeditor_selected_tile.bmp", NULL);
	
	
	// set up editor mode
	mW_mapeditor_editing = mW_MAPEDITOR_EDITING_TILES;
	
	
	// set up mapeditor map
	mW_mapeditor_map = mW_map_create(8, 8);
	
	// remove the game drawing interrupt
	remove_int(mW_game_draw);
	// install a timer to draw the mapeditor
	if (install_int_ex(mW_mapeditor_draw, MSEC_TO_TIMER(33)) != 0)
	{
		printf("Error setting mapeditor draw timer\n");
		// if this fails the world ends anyway
		install_int_ex(mW_game_draw, MSEC_TO_TIMER(33));
		return 0;
	}

	while (keep_map_editing == 1)
	{
	
		while (keypressed())
		{

			key = mW_keyboard_get_char();
	
			// return key
			if (key == 13)
			{
				if (mW_mapeditor_text_interface() == 0)
					printf("Error with your command\n");
			}
			
			// escape key	
			else if (key == 27)
			{
				keep_map_editing = 0;
				break;
			}
				
		}
		
		interface_input = mW_interface_input();
		if ((interface_input == 0) && (mouse_b == 1))
		{
			mW_mapeditor_handle_mouse();
		}
		else if (interface_input == 2)
		{
			printf("1\n");
			mW_game_select_input();
		}
		
		mW_mouse_delete_all_clicks();
		
		rest(10);
		
	}
	

	// remove the mapeditor drawing interrupt
	remove_int(mW_mapeditor_draw);
	// reinstall the timer to draw the game
	if (install_int_ex(mW_game_draw, MSEC_TO_TIMER(33)) != 0)
	{
		printf("Error resetting the game draw timer\n");
		return 0;
	}
	
	free(mW_mapeditor_img_over_tile);
	free(mW_mapeditor_selected_tile);
	
	mW_map_destroy(mW_mapeditor_map);
	
	return 1;
	
}

					
int mW_mapeditor_text_interface ()
{

	int i;
	
	unsigned short height = 0;
	unsigned short width = 0;
	
	char * command_string;


	command_string = mW_keyboard_input_string(32);
	
	// new <map_width> <map_height>
	if (memcmp(command_string, "new", 3) == 0)
	{
	
		#if DEBUG == 1
			printf("creating new map\n");
		#endif
		
		i = mW_get_unsigned_short_from_string((const char *) &command_string[4]);
		
		#if DEBUG == 1
			printf("get_unsigned_short result %d\n", i);
		#endif
		
		if (i < 0)
		{
			free(command_string);
			return 0;
		}
		width = (unsigned short) i;
		
		#if DEBUG == 1
			printf("width assigned %hu\n", width);
		#endif
		
		for (i = 0; i < 6; i++)
		{
			if (command_string[4+i] == ' ')
			{
				#if DEBUG == 1
					printf("command_string[5+%d] = %s\n", i, &command_string[5+1]);
				#endif
				i = mW_get_unsigned_short_from_string((const char *) &command_string[5+i]);
				#if DEBUG == 1
					printf("result i: %d\n", i);
				#endif
					
				break;
			}
		}
		
		if (i < 0)
		{
			free(command_string);
			return 0;
		}
		height = (unsigned short) i;
		
		#if DEBUG == 1
			printf("height assigned %hu\n", height);
		#endif
		
		if ((width < 1) || (height < 1))		{
			free(command_string);
			return 0;
		}

		
		mW_map_destroy(mW_mapeditor_map);
		
		#if DEBUG == 1
			printf("map destroyed\n");
		#endif
		
		mW_mapeditor_map = mW_map_create(height, width);
		
		#if DEBUG == 1
			printf("new map created\n");
		#endif
		
		if (i == 0)
		{
			free(command_string);
			return 0;
		}
		
		#if DEBUG == 1
			printf("Map created, everything looks good.\n");
		#endif
		
		free (command_string);

		return 1;
			
	}
	else if (memcmp(command_string, "passable", 8) == 0)
	{
		
		mW_mapeditor_editing = mW_MAPEDITOR_EDITING_PASSABLE;
		mW_mapeditor_map->flags |= mW_MAP_SHOW_PASSABLE;
		
		free(command_string);
		return 1;
		
	}
	else if (memcmp(command_string, "nonpassable", 11) == 0)
	{
		
		mW_mapeditor_editing = mW_MAPEDITOR_EDITING_NONPASSABLE;
		mW_mapeditor_map->flags |= mW_MAP_SHOW_PASSABLE;
		
		free(command_string);
		return 1;
		
	}
	else if (memcmp(command_string, "tiles", 5) == 0)
	{
		
		mW_mapeditor_editing = mW_MAPEDITOR_EDITING_TILES;
		mW_mapeditor_map->flags &= ~mW_MAP_SHOW_PASSABLE;
		
		free(command_string);
		return 1;
		
	}
	else
	{
		free(command_string);
		return 0;
	}

}
